﻿using OAuth2Authorizer.Serialization;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;

namespace OAuth2Authorizer.Framework
{
    // Will be used to serve any "authentic" OAuth2 Service Provider
    internal class GenericAuthorizer : AuthorizerBase, IAuthorizer
    {
        internal string AuthorizeUrl { get; set; }

        // We have to build this one out
        internal string AuthorizeUrlTemplate { get; set; }
        internal bool UseState { get; set; }

        // We have to build this one out
        internal string TokenRequestTemplate { get; set; }

        // using the longer form because _tokenUrl is defined in the base class
        internal string TokenUrl
        {
            get { return _tokenUrl; }
            set { _tokenUrl = value; }
        }

        public Type ResponseType { get; set; }

        public GenericAuthorizer() : base(string.Empty) { }
        protected override string GetAuthorizeUrlInternal(string appKey, string redirectUrl, string state)
        {
            return UseState ? string.Format(AuthorizeUrlTemplate, AuthorizeUrl, appKey, redirectUrl, state) : string.Format(AuthorizeUrlTemplate, AuthorizeUrl, appKey, redirectUrl);
        }

        protected override NameValueCollection GetTokenRequestParameters(string appKey, string appSecret, string redirectUrl, string code)
        {
            var serializer = new NameValueCollectionSerializer();
            var tokenString = string.Format(TokenRequestTemplate, appKey, appSecret, redirectUrl, code);
            return serializer.GetCollection(tokenString);
        }

        protected override AccessTokenResponse GetResponseObject(Stream stream, string contentType)
        {
            dynamic serializer = typeof(SerializerFactory).GetMethod("CreateSerializer").MakeGenericMethod(ResponseType).Invoke(null, new object[] { contentType });
            dynamic dynamicResponse = serializer.ReadObject(stream);
            return dynamicResponse.AsAccessTokenResponse();
        }
    }
}
